#pragma once

#include <vector>
#include "oratypes.h"
#include "oci.h"
#include "FMDBRecordSet.h"

//note: parameter do not release storage memory, the caller should release it

class FMDBParameter
{
public:
	FMDBParameter(TCHAR *VarName,int *VarValueArray);
	FMDBParameter(TCHAR *VarName,long *VarValueArray);
	FMDBParameter(TCHAR *VarName,TCHAR *VarValueArray);
	FMDBParameter(TCHAR *VarName,double *VarValueArray);
	FMDBParameter(void);
	~FMDBParameter(void);

	void Set(TCHAR *VarName,void* VarValueArray, ub2 ub2VarDataType);
	void Set(TCHAR *VarName,int *VarValueArray);
	void Set(TCHAR *VarName,long *VarValueArray);
	void Set(TCHAR *VarName,TCHAR *VarValueArray);
	void Set(TCHAR *VarName,double *VarValueArray);

	TCHAR* GetVarName(){return m_pstrVarName;}
	ub2 GetVarOraDataType(){return m_VarDataType;}
	(void *)GetVarValue(){return m_VarValue;}
	void SetIndicator(short* val){m_pIndicator=val;}
	short* GetIndicator(){return m_pIndicator;}
	ub4 GetVarSize(){return m_VarSize;}
	void SetVarSize(ub4 val){ m_VarSize=val;}

private:
	TCHAR *m_pstrVarName;
	void *m_VarValue;
	ub2 m_VarDataType;
	short *m_pIndicator;
	ub4 m_VarSize;
};

class FMDBIOVParameter
{
public:
	FMDBIOVParameter(TCHAR *VarName,OCIIOV *VarValueArray,ub4 ArraySize,ub2 VarOraDataType);
	~FMDBIOVParameter(void)
	{
		delete m_pstrVarName;
		delete m_VarValue;
	}
	TCHAR* GetVarName(){return m_pstrVarName;}
	ub2 GetVarOraDataType(){return m_VarDataType;}
	ub4 GetVarArraySize(){return m_ValueArraySize;}
	(OCIIOV *)GetVarValue(){return m_VarValue;}

private:
	TCHAR *m_pstrVarName;
	OCIIOV *m_VarValue;
	ub4 m_ValueArraySize;
	ub2 m_VarDataType;

};

class FMDBCursorParameter
{
public:
	FMDBCursorParameter(TCHAR *VarName);
	~FMDBCursorParameter(void);

	TCHAR* GetVarName(){return m_pstrVarName;}
	ub2 GetVarOraDataType(){return SQLT_RSET;}
	void* GetVarValue(){return m_VarValue;}
	void SetVarValue(void *val){m_VarValue=val;}
	FMDBRecordSet* GetRecordset() { return &m_pRs; }
private:
	TCHAR *m_pstrVarName;
	void *m_VarValue;//this is a pointer to OCIStmt handle
	FMDBRecordSet m_pRs;//recordset for this oci parameter statement
};

class FMDBCLOBParameter
{
public:
	FMDBCLOBParameter(TCHAR *VarName);
	~FMDBCLOBParameter(void);

	TCHAR* GetVarName(){return m_pstrVarName;}
	ub2 GetVarOraDataType(){return SQLT_CLOB;}
	void* GetVarValue(){return m_VarValue;}
	void SetVarValue(void *val){m_VarValue=val;}
private:
	TCHAR *m_pstrVarName;
	void *m_VarValue;//this is a pointer to OCILobLocator 
};

class FMDBParameters
{
public:
	FMDBParameters(void){};
	~FMDBParameters(void);

	FMDBParameter* AddParam(TCHAR *VarName, void* pVarValueArray, ub2 ub2VarDataType, ub4 ub4Size, short* pIndicator);
	void AddOCIIOVParam(FMDBIOVParameter *Param);
	FMDBCursorParameter* AddCursorParam(TCHAR *VarName);
	FMDBCLOBParameter* AddCLOBParam(TCHAR *VarName);

	std::vector<FMDBParameter *> GetParameters(){return m_vParam;}
	std::vector<FMDBIOVParameter *> GetIOVParameters(){return m_vIOVParam;}
	std::vector<FMDBCursorParameter *> GetCursorParameters(){return m_vCursorParam;}
	std::vector<FMDBCLOBParameter *> GetCLOBParameters(){return m_vCLOBParam;}

	void Clear();

private:
	std::vector<FMDBParameter *> m_vParam;
	std::vector<FMDBIOVParameter *> m_vIOVParam;
	std::vector<FMDBCursorParameter *> m_vCursorParam;
	std::vector<FMDBCLOBParameter *> m_vCLOBParam;
};